import { useSessionStorage } from '@/hooks/useSessionStorage'
import { LoadingOutlined, PlusOutlined } from '@ant-design/icons'
import { useMessage } from '@hooks/useAppMessage'
import { useCookie } from '@hooks/useCookie'
import { Image, Upload } from 'antd'
import classNames from 'classnames'
import { useEffect, useRef, useState } from 'react'

const options = {
  image: {
    maxSize: 2, // 2MB
    mineTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
  },
  video: {
    maxSize: 50, // 50MB
    mineTypes: [
      'video/mp4',
      'video/quicktime',
      'video/x-ms-wmv',
      'video/x-msvideo',
      'video/x-flv',
      'video/webm',
    ],
  },
}

/**
 *
 * @param {String} key 唯一标识
 * @param {String} type image|video 图片|视频
 * @param {String} url 图片地址
 * @param {String} aspect 宽高比
 * @param {Function} onChange 上传成功回调
 * @returns
 */
export default function ImagePreview({
  key = 'image-preview',
  type = 'image',
  url,
  aspect = '4:3',
  onChange,
}) {
  const config = options[type]
  const fileinfo = useRef({})

  const [src, setSrc] = useState(null)
  const [loading, setLoading] = useState(false)

  const message = useMessage()
  const cookie = useCookie()
  const xsrfToken = cookie.get('XSRF-TOKEN') ?? undefined
  const [token] = useSessionStorage('token', null)

  useEffect(() => {
    url && setSrc(url)
  }, [url])

  const handleChange = (info) => {
    console.log('%c Line:12 🥤 info', 'color:#2eafb0', info)
    fileinfo.current = info.file
    if (info.file.status === 'uploading') {
      setLoading(true)
      return
    }
    if (info.file.status === 'done') {
      // Get this url from response in real world.
      getBase64(info.file.originFileObj, (url) => {
        setLoading(false)
        setSrc(url)
      })
    }

    // 触发父组件的onChange事件
    onChange?.(info.file.response)
  }

  const getBase64 = (img, callback) => {
    const reader = new FileReader()
    reader.addEventListener('load', () => callback(reader.result))
    reader.readAsDataURL(img)
  }
  const beforeUpload = (file) => {
    if (!config.mineTypes.includes(file.type)) {
      const mineType = config.mineTypes.map((t) => t.split('/').pop()).join('、')
      message.error(`文件格式错误，请选择${mineType}格式`)
      return false
    }

    const fileSize = file.size / 1024 / 1024 // ?M
    if (fileSize > config.maxSize) {
      message.error(`文件大小不能超过${config.maxSize}M`)
      return false
    }

    return true
  }

  const calcHeight = (aspect) => {
    const [width, height] = aspect.split(':')
    const w = (100 / height) * width
    return w
  }

  const commonProps = {
    src: src,
    className: classNames(
      `rounded-md border border-gray-500/30 overflow-hidden`,
      `aspect-[${aspect.replace(':', '/')}] `,
      { 'bg-gray-50': !src },
    ),
    width: calcHeight(aspect),
    style: {
      width: calcHeight(aspect),
      height: '100px',
      objectFit: 'cover',
      objectPosition: 'center',
    },
    preview: {
      scaleStep: 0.5,
      src: src,
    },
  }

  return (
    <div className="flex gap-2">
      <Upload
        key={key}
        className="file-uploader"
        listType="picture-card"
        showUploadList={false}
        action="/api/admin/upload"
        name="file"
        headers={{
          'X-XSRF-TOKEN': xsrfToken,
          authorization: token ? `Bearer ${token}` : undefined,
        }}
        accept={config.mineTypes.join(',')}
        beforeUpload={beforeUpload}
        onChange={handleChange}>
        <button style={{ border: 0, background: 'none' }} type="button">
          {loading ? <LoadingOutlined /> : <PlusOutlined />}
          <div style={{ marginTop: 4 }}>
            <div>上传</div>
            {aspect && <div className="text-rose-400 text-xs">比例{aspect}</div>}
          </div>
        </button>
      </Upload>

      {type === 'image' && src && <Image key={src} {...commonProps} />}

      {type === 'video' && src && <video key={src} {...commonProps} controls />}
    </div>
  )
}
